/*
 * @Description 
 * @Autor lzhiqiang
 * @Date 2023-02-25 16:32:47
 * @LastEditors lzhiqiang
 * @LastEditTime 2023-04-05 20:48:14
 */
#ifndef __UTIL_H__ 
#define __UTIL_H__

#include <pthread.h>
#include <unistd.h>
#include <stdint.h>
#include <iostream>
#include <vector>
#include <string>
#include <boost/lexical_cast.hpp>

namespace johnsonli
{
	/**
	 * @brief 返回当前线程的ID
	 */
	pid_t getThreadId();

	/**
	 * @brief 返回当前协程的ID
	 */
	uint32_t getFiberId();

	//捕获栈信息
	void Backtrace(std::vector<std::string>& bt, int size, int skip);
	//捕获栈信息，并转换成string
	std::string BacktraceToString(int size=64, int skip = 2, const std::string& prefix = "");

	uint64_t GetCurrentMS();
	uint64_t GetCurrentUS();

	std::string Time2Str(time_t ts = time(0), const std::string& format = "%Y-%m-%d %H:%M:%S");
	time_t Str2Time(const char* str, const char* format = "%Y-%m-%d %H:%M:%S");

	class StringUtil {
	public:
		static std::string Format(const char* fmt, ...);
		static std::string Formatv(const char* fmt, va_list ap);

		static std::string UrlEncode(const std::string& str, bool space_as_plus = true);
		static std::string UrlDecode(const std::string& str, bool space_as_plus = true);

		static std::string Trim(const std::string& str, const std::string& delimit = " \t\r\n");
		static std::string TrimLeft(const std::string& str, const std::string& delimit = " \t\r\n");
		static std::string TrimRight(const std::string& str, const std::string& delimit = " \t\r\n");


		static std::string WStringToString(const std::wstring& ws);
		static std::wstring StringToWString(const std::string& s);

	};

	class FSUtil {
	public:
		static void ListAllFile(std::vector<std::string>& files
                            ,const std::string& path
                            ,const std::string& subfix);
	
		static bool Mkdir(const std::string& dirname);
    	static bool IsRunningPidfile(const std::string& pidfile);
	};

	template<class V, class Map, class K>
	V GetParamValue(const Map& m, const K& k, const V& def = V()) {
		auto it = m.find(k);
		if(it == m.end()) {
			return def;
		}
		try {
			return boost::lexical_cast<V>(it->second);
		} catch (...) {
		}
		return def;
	}

	class TypeUtil {
	public:
		static int8_t ToChar(const std::string& str);
		static int64_t Atoi(const std::string& str);
		static double Atof(const std::string& str);
		static int8_t ToChar(const char* str);
		static int64_t Atoi(const char* str);
		static double Atof(const char* str);
	};
}



#endif // !
